#include "materiallist.h"
#include <QScroller>
#include <QPainterPath>
#include <QMessageBox>
#include "dataprovider.h"
#include "utils.h"

// ********************* MaterialList *************************/
MaterialList::MaterialList(QWidget *parent)
    :QListView(parent){
    setFixedWidth(382);
    setDragEnabled(true);
    setVerticalScrollMode(QListView::ScrollPerPixel);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setSelectionMode(QAbstractItemView::SingleSelection);
    setAttribute(Qt::WA_AcceptTouchEvents, true);
    QScroller::grabGesture(this, QScroller::TouchGesture);
    setLayoutMode(QListView::Batched);
    setResizeMode(QListView::Adjust);
    setBatchSize(50);

    setViewMode(QListView::IconMode);
    setFlow(QListView::LeftToRight);
    setWrapping(true);
    setSpacing(6);

    delegate = new MaterialListDelegate(this);

    setModel(&model);
    setItemDelegate(delegate);

    setStyleSheet(R"(
        QListView { border: 1px solid #DCDFE6;}
        QListView::item:hover { background: #F5F7FA; }
    )");

    viewport()->installEventFilter(this);
    lastClickTime = QDateTime::currentMSecsSinceEpoch();

    setupConnections();
}

void MaterialList::setupConnections() {
    // connect(this, &QListView::clicked, this, &MaterialList::itemClicked);
}

bool MaterialList::eventFilter(QObject *obj, QEvent *event){

    if (event->type() == QEvent::MouseButtonPress) {
        // qDebug() << "eventFilter... touchBegin";
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);

        firstTouchTime = QDateTime::currentMSecsSinceEpoch();
        firstTouchPos = mouseEvent->localPos();
        // QMessageBox::warning(this, "触摸", "开始触摸", QMessageBox::Ok);

    } else if (event->type() == QEvent::MouseButtonRelease) {
        // qDebug() << "eventFilter... touchEnd";
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        QPointF currentPos = mouseEvent->localPos();
            qreal delta = (currentPos - firstTouchPos).manhattanLength();
            qint64 duration = QDateTime::currentMSecsSinceEpoch() - firstTouchTime;
            // qDebug()<< "duration: " << duration << "; delta: " << delta;
            // printf("duration: %d, delta: %d\n", duration, delta);

            if (duration < 300 && delta < 100) {
                QModelIndex index = indexAt(currentPos.toPoint());
                // qDebug() << "itemClicked";
                itemClicked(index);
            }
        return true;

    }

    return QWidget::eventFilter(obj, event);
}

void MaterialList::itemClicked(const QModelIndex &index) {
    qint64 now = QDateTime::currentMSecsSinceEpoch();
    if (now - lastClickTime < 2000) {
        return;
    }
    lastClickTime = now;
    int id = index.data(MaterialId).toInt();
    // qDebug() << "双击的数据：" << id;
    auto dataProvider = DataProvider::instance();
    dataProvider->CreateRecordByMaterial(id);
}


// ********************* MaterialListModel *************************/
MaterialListModel::MaterialListModel(QObject* parent):
    QAbstractListModel(parent) {
    LoadItems();
    setupConnections();
}

int MaterialListModel::rowCount(const QModelIndex &parent) const {
    Q_UNUSED(parent);
    return materials.size();
}

QVariant MaterialListModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid()) return QVariant();

    const auto &item = materials[index.row()];
    switch (role) {
    case Qt::DisplayRole:
        return item->Name;
    case MaterialId:
        return item->Id;
    case VailCount:
        return QString("赏味期: %1, %2")
            .arg(GetOperationTypeString(item->OperationType))
            .arg(GetValidityCountString(item->DateUnit, item->DateCount));
    case SaveType:
        return "存储: " + GetSaveTypeString(item->SaveType);
    default:
        return QVariant();
    }
}

void MaterialListModel::setupConnections(){
    auto dataProvider = DataProvider::instance();
    connect(dataProvider, &DataProvider::materialListUpdate, this, &MaterialListModel::LoadItems);
}

void MaterialListModel::LoadItems() {
    beginResetModel();
    auto dataProvider = DataProvider::instance();
    QList<Material*> list = dataProvider->GetMaterials();
    materials.clear();
    materials = list.toVector();
    endResetModel();
}



// ********************* MaterialListDelegate *************************/
void MaterialListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    QFont font;
    QRect textRect;
    QColor mainTextColor(qRgb(40, 40, 40));
    QColor otherTextColor(qRgb(80, 80, 80));

    painter->save();
    painter->setRenderHint(QPainter::Antialiasing, true);

    QPainterPath path;
    QPen pen;
    pen.setWidth(3);
    path.addRoundedRect(option.rect.adjusted(1, 1, -1, -1), 5, 5);
    if (option.state & QStyle::State_Selected) {
        pen.setColor(QColor(qRgb(43, 43, 115)));
        painter->setPen(pen);
        painter->drawPath(path);
        painter->fillPath(path, QColor(qRgb(75, 127, 210)));
        mainTextColor = qRgb(250, 250, 250);
        otherTextColor = qRgb(200, 200, 200);
    } else {
        pen.setColor(QColor(qRgb(200, 200, 200)));
        painter->setPen(pen);
        painter->drawPath(path);
        painter->fillPath(path, QColor(qRgb(249, 250, 251)));
    }

    // 绘制品名
    font.setBold(true);
    font.setPointSize(9);
    textRect = option.rect.adjusted(10, 5, -5, -5);
    painter->setPen(mainTextColor);
    painter->setFont(font);
    painter->drawText(textRect, Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap, index.data(Qt::DisplayRole).toString());

    // 绘制效期时间
    font.setBold(false);
    font.setPointSize(7);
    textRect = option.rect.adjusted(10, 28, -5, -5);
    painter->setPen(otherTextColor);
    painter->setFont(font);
    painter->drawText(textRect, Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap, index.data(VailCount).toString());

    // 绘制保存方式
    font.setBold(false);
    font.setPointSize(6);
    textRect = option.rect.adjusted(10, 48, -5, -5);
    painter->setPen(otherTextColor);
    painter->setFont(font);
    painter->drawText(textRect, Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap, index.data(SaveType).toString());

    painter->restore();
}

QSize MaterialListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &) const {
    Q_UNUSED(option);
    // auto view = option.widget;
    // int totalWidth = view->width() - view->contentsMargins().left() - view->contentsMargins().right();
    // int itemWidth = (totalWidth - 6 * 3) / 2; // 两列需减3个间距
    return QSize(180, 70);
}
